import {Injectable, OnModuleInit} from "@nestjs/common";
import {InjectRepository} from "@nestjs/typeorm";
import {SysRole} from "../entity/SysRole";
import {Repository} from "typeorm";
import config from "../config";
import {DefaultEnum} from "../common/enum/DefaultEnum";
import {INIT_CONSTANTS} from "../InitProjectConstant";
import {SysMenu} from "../entity/SysMenu";
import {PageQuery} from "../common/page/PageQuery";
import {SysRoleDto} from "../dto/SysRoleDto";
import {RoleEnum} from "../common/enum/RoleEnum";
import {ObjectUtils} from "../common/utils/ObjectUtils";
import {JwtConstant} from "../common/constant/JwtConstant";
import {Result} from "../common/Result";
import {BaseEntity} from "../entity/BaseEntity";

/**
 * 系统角色Service
 */
@Injectable()
export class SysRoleService implements OnModuleInit{
    @InjectRepository(SysRole)
    private sysRoleRepository: Repository<SysRole>;

    async onModuleInit() {
        if (!config.doInit) {
            return;
        }
        let list: SysRole[] = [];
        let name: string[] = INIT_CONSTANTS.roles.names;
        let menus = INIT_CONSTANTS.menus;
        for (let i = 0; i < name.length; i++) {
            let sysRole = new SysRole();
            sysRole.roleId = i + 1;
            sysRole.roleName = name[i];
            sysRole.isDefault = DefaultEnum.DEFAULT;
            sysRole.level = i + 1;
            sysRole.type  = i + 1;
            sysRole.menus = [];
            sysRole.init(1);

            for (let j = 0; j < menus.length - 1; j++) {
                for (let k = 0; k < menus[j].length; k++) {
                    let menu = new SysMenu();
                    menu.menuId = menus[j][k].menuId
                    sysRole.menus = [...sysRole.menus, menu]
                }
            }
            // 管理员
            if (sysRole.roleId == 1) {
                for (let j = menus.length - 1; j < menus.length; j++) {
                    for (let k = 0; k < menus[j].length; k++) {
                        let menu = new SysMenu();
                        menu.menuId = menus[j][k].menuId
                        sysRole.menus = [...sysRole.menus, menu]
                    }
                }
            }

            list.push(sysRole);
        }
        // console.log("看看角色: ", list);
        await this.sysRoleRepository.save(list).then(r => {
            console.log("初始化角色成功!")
        });
    }


    /**
     * 角色列表查询
     * @param query
     */
    async roleList( query: PageQuery<SysRoleDto>) {
        let queryBuilder = this.sysRoleRepository.createQueryBuilder("r")
            .where("1=1");
        let param = query.param;
        if (param?.roleName) {
            queryBuilder.andWhere(`r.role_name like '%${param.roleName}%'`);
        }
        if (param?.type) {
            queryBuilder.andWhere(`r.type = ${param.type}`);
        }
        if (PageQuery.isPage(query)) {
            queryBuilder.offset(PageQuery.skip(query)).limit(query.pageSize)
        }
        let data = await queryBuilder.getManyAndCount();
        let vo: SysRoleDto[] = [];
        data[0].map(item => {
            let obj = new SysRoleDto();
            ObjectUtils.copyProperties(item, obj);
            obj.typeName = RoleEnum.format(item.type);
            vo.push(obj);
        })
        data[0] = vo;
       return data;
    }

    /**
     * 角色种类查询
     */
    async types() {
        return [RoleEnum.ADMIN, RoleEnum.SYS_MANAGER, RoleEnum.STORE_MANAGER, RoleEnum.STORE_ASSISTANT];
    }

    /**
     * 编辑或添加角色
     * @param dto
     */
    async upsertRole(dto: SysRoleDto) {
        let sysRole = new SysRole();
        ObjectUtils.copyProperties(dto, sysRole);
        let userId = JwtConstant.getUserId();
        if (dto.roleId) {
            // 编辑
            sysRole.initUpdate(userId);
            await this.sysRoleRepository.update(sysRole.roleId, sysRole);
        } else {
            // 添加
            sysRole.init(userId);
            await this.sysRoleRepository.save(sysRole);
        }
        return Result.success();

    }

    /**
     * 删除角色
     * @param dto
     */
    async deleteRole(dto: SysRoleDto) {
        let one = await this.sysRoleRepository.findOneBy({roleId: dto.roleId});
        if (!one) {
            return Result.failed("数据异常!");
        }
        await this.sysRoleRepository.delete(dto.roleId);
        return Result.success();
    }
}
